﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using iTFF.WinFormsWrappers;
using System.Windows.Input;
using iTFF.WPF.CP;
using System.Windows;
using System.Windows.Data;
using System.Collections.Specialized;
using System.Windows.Controls;

namespace iTFF.WPF.ViewModel
{
    class MainWindowViewModel : WorkspaceViewModel
    {

        #region Fields

        ObservableCollection<WorkspaceViewModel> _workspaces;
        ObservableCollection<TabItem> _tabItems;
        ControlPanel _cp;
        WindowState _windowState;
        RelayCommand _notifyIconMouseDoubleClickCommand;
        RelayCommand _showGlobalHotKeysCommand;
        RelayCommand _showArtworkCommand;
        RelayCommand _showLyricsCommand;
        RelayCommand _downloadTagsCommand;
        RelayCommand _showPreferencesCommand;

        #endregion

        #region Contructor

        public MainWindowViewModel()
        {
            _cp = ControlPanel.Instance;
            Workspaces.Add(new GlobalHotKeysViewModel());
            Workspaces.Add(new ArtworksViewModel());
            Workspaces.Add(new PreferencesViewModel());

            SetActiveWorkspace(typeof(PreferencesViewModel));

            // link with itunes
            var ins = ControlPanel.Instance.iTunesControlPanel;
        }

        #endregion

        #region Worskpaces

        /// <summary>
        /// The workspaces collection
        /// </summary>
        public ObservableCollection<WorkspaceViewModel> Workspaces
        {
            get
            {
                if (_workspaces == null)
                {
                    _workspaces = new ObservableCollection<WorkspaceViewModel>();
                    _workspaces.CollectionChanged += this.OnWorkspacesChanged;
                }
                return _workspaces;
            }
        }

        /// <summary>
        /// Adds or removes the tabitems
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnWorkspacesChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems != null && e.NewItems.Count != 0)
            {
                foreach (WorkspaceViewModel workspace in e.NewItems)
                {
                    workspace.RequestClose += this.OnWorkspaceRequestClose;

                    // Create a TabItem, specifying content in a ContentControl
                    // This is a workaround to skip the view creation each time a tab is displayed
                    var ti = new TabItem()
                    {
                        Content = new ContentControl() { Content = workspace },
                        Header = workspace.DisplayName,
                    };

                    TabItems.Add(ti);
                }
            }

            if (e.OldItems != null && e.OldItems.Count != 0)
            {
                foreach (WorkspaceViewModel workspace in e.OldItems)
                {
                    workspace.RequestClose -= this.OnWorkspaceRequestClose;
                    TabItems.Remove(GetTabItemFromWorkspace(workspace));
                }
            }
        }

        /// <summary>
        /// Removes the workspace
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnWorkspaceRequestClose(object sender, EventArgs e)
        {
            WorkspaceViewModel workspace = sender as WorkspaceViewModel;
            workspace.Dispose();
            this.Workspaces.Remove(workspace);
        }

        /// <summary>
        /// Gets the TabItem from the workspace
        /// </summary>
        /// <param name="workspace"></param>
        /// <returns></returns>
        TabItem GetTabItemFromWorkspace(WorkspaceViewModel workspace)
        {
            return TabItems.FirstOrDefault(t => (string)t.Header == workspace.DisplayName);
        }

        public ObservableCollection<TabItem> TabItems
        {
            get
            {
                if (_tabItems == null)
                {
                    _tabItems = new ObservableCollection<TabItem>();
                }
                return _tabItems;
            }
        }

        /// <summary>
        /// Sets the active workspace (Tab)
        /// </summary>
        /// <param name="t"></param>
        void SetActiveWorkspace(Type t)
        {
            var ws = Workspaces.FirstOrDefault(w => w.GetType() == t);
            if (ws != null)
            {
                var cv = CollectionViewSource.GetDefaultView(TabItems);
                if (cv != null)
                    cv.MoveCurrentTo(GetTabItemFromWorkspace(ws));
            }
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets the current Window State
        /// </summary>
        public WindowState WindowState
        {
            get { return _windowState; }
            set
            {
                if (_windowState != value)
                {
                    _windowState = value;
                    OnPropertyChanged("WindowState");
                    OnPropertyChanged("ShowInTaskbar");
                }
            }
        }

        /// <summary>
        /// Gets the Show In Taskbar status. Depends on if the window i sminimized or not;
        /// </summary>
        public bool ShowInTaskbar
        {
            get { return WindowState != WindowState.Minimized; }
        }

        #endregion

        #region Private properties

        public ControlPanel CP
        {
            get { return _cp; }
        }

        #endregion

        #region Commands

        /// <summary>
        /// Show the main window when double click on the notify icon
        /// </summary>
        public ICommand NotifyIconMouseDoubleClickCommand
        {
            get
            {
                if (_notifyIconMouseDoubleClickCommand == null)
                    _notifyIconMouseDoubleClickCommand = new RelayCommand(param => OnNotifyconMouseDoubleClick());
                return _notifyIconMouseDoubleClickCommand;
            }
        }

        /// <summary>
        /// Show the main window when double click on the notify icon
        /// </summary>
        private void OnNotifyconMouseDoubleClick()
        {
            WindowState = WindowState.Normal;
            ControlPanel.Instance.ShowMainWindow();
        }

        /// <summary>
        /// Shows the GlobalHotkey tab
        /// </summary>
        public ICommand ShowGlobalHotKeysCommand
        {
            get
            {
                if (_showGlobalHotKeysCommand == null)
                    _showGlobalHotKeysCommand = new RelayCommand(param => OnShowGlobalHotKeysCommand(param));
                return _notifyIconMouseDoubleClickCommand;
            }
        }

        /// <summary>
        /// Shows the GlobalHotkey tab
        /// </summary>
        /// <param name="param"></param>
        private void OnShowGlobalHotKeysCommand(object param)
        {
            ControlPanel.Instance.ShowMainWindow();
            SetActiveWorkspace(typeof(GlobalHotKeysViewModel));
        }

        /// <summary>
        /// Shows the artwork tab and get artworks for selected files
        /// </summary>
        public ICommand ShowArtworkCommand
        {
            get
            {
                if (_showArtworkCommand == null)
                    _showArtworkCommand = new RelayCommand(param => OnShowArtworkCommand(param));
                return _notifyIconMouseDoubleClickCommand;
            }
        }

        /// <summary>
        /// Shows the artwork tab and get artworks for selected files
        /// </summary>
        /// <param name="param"></param>
        private void OnShowArtworkCommand(object param)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Shows the lyrics Window
        /// </summary>
        public ICommand ShowLyricsCommand
        {
            get
            {
                if (_showLyricsCommand == null)
                    _showLyricsCommand = new RelayCommand(param => OnShowLyricsCommand(param));
                return _notifyIconMouseDoubleClickCommand;
            }
        }

        /// <summary>
        /// Shows the lyrics Window
        /// </summary>
        /// <param name="param"></param>
        private void OnShowLyricsCommand(object param)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Downloads tags for selected songs
        /// </summary>
        public ICommand DownloadTagsCommand
        {
            get
            {
                if (_downloadTagsCommand == null)
                    _downloadTagsCommand = new RelayCommand(param => OnDownloadTagsCommand(param));
                return _notifyIconMouseDoubleClickCommand;
            }
        }

        /// <summary>
        /// Downloads tags for selected songs
        /// </summary>
        /// <param name="param"></param>
        private void OnDownloadTagsCommand(object param)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Shows preferences tab
        /// </summary>
        public ICommand ShowPreferencesCommand
        {
            get
            {
                if (_showPreferencesCommand == null)
                    _showPreferencesCommand = new RelayCommand(param => OnShowPreferencesCommand(param));
                return _notifyIconMouseDoubleClickCommand;
            }
        }

        /// <summary>
        /// Shows preferences tab
        /// </summary>
        /// <param name="param"></param>
        private void OnShowPreferencesCommand(object param)
        {
            throw new NotImplementedException();
        }
        #endregion
    }
}
